#include "PokerPlayer.h"
#include "PokerLogic.h"

void PokerPlayer::delayNotify(PLAYER_STATE state, int32_t card, float delayTime) {
    if (delayTime > 0.001f) {
        DelayCall::add([this, state, card](int, bool, int& count) {
            for (auto& item : m_theListener) {
                if (item != nullptr) {
                    item(this, state, card);
                }
            }
        }, delayTime);
    } else {
        for (auto& item : m_theListener) {
            if (item != nullptr) {
                item(this, state, card);
            }
        }
    }
}

void PokerPlayer::over() {
    delayNotify(PLAYER_STATE::ON_INFO_CHANGE, -1);
}

// 不换人再来一局, 收回手头的牌
void PokerPlayer::onceMore() {
    m_cards.clear();
    m_cardsLastOut.clear();
    theCardGroups.clear();
}

void PokerPlayer::sortCards() {
    auto fun = [](int a, int b) {
        int32_t num1 = a % 100;
        int32_t tag1 = (int32_t)(a / 100);
        int32_t num2 = b % 100;
        int32_t tag2 = (int32_t)(b / 100);
        if (num1 == num2) {
            return tag1 < tag2;//牌面相同的按照黑红梅方排序
        }
        return num1 > num2;//牌面不同的直接按照牌面排序
    };
    std::sort(m_cards.begin(), m_cards.end(), fun);
}

void PokerPlayer::cardOut() {
    // 出牌
    delayNotify(PLAYER_STATE::ON_CARD_OUT_START, -1);
    if (this->isLocalPlayer()) {
        // 玩家需要自己操控，不帮他，除非他选择挂机操作
        return;
    }
    DelayCall::add([this](int tick, bool last, int& count) {
        std::vector< int32_t > data;
        tryOutputCard(data, false);
        doCardOut(data);
    }, 0.75f);
}

void PokerPlayer::tryOutputCard(std::vector<int32_t>& data, bool forSuggestTips) {
    // 排序
    sortCards();
    // 分析手牌
    PokerLogic::doAnalysis(m_cards, theCardGroups);
    // 拉到上家出的牌
    std::vector< int32_t > cardsLastOut;
    uint8_t seat = PokerLogic::shard()->getRealSeat(m_seat, -1);
    PokerLogic::shard()->getPlayer(seat)->getLastOutCards(cardsLastOut);
    if (cardsLastOut.empty()) {
        // 上家没出? 再找上上家看看
        seat = PokerLogic::shard()->getRealSeat(m_seat, -2);
        PokerLogic::shard()->getPlayer(seat)->getLastOutCards(cardsLastOut);
    }
    data.clear();
    if (cardsLastOut.empty()) {
        // 斗地主,3个人参与,此时前两家都没出牌,那就随便出喽
        data = selectCard(forSuggestTips);
    } else {
        // 根据别人的牌,优选自己的出牌方式,必须能大过对方 
        data = selectCard(seat, cardsLastOut, forSuggestTips);
    }
//#if COCOS2D_DEBUG > 0
//    const char* tmp[] = {"3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A", "2", "XW", "DW"};
//    std::cout << "OutputCard: ";
//    for (auto&& i : data) std::cout << tmp[i] << ", ";
//    std::cout << std::endl;
//#endif
    std::vector< int32_t > handCard;
    handCard.assign(m_cards.begin(), m_cards.end());
    // data是不带花色的
    for (size_t j = 0; j < data.size(); j++) {
        for (size_t i = 0; i != handCard.size(); i++) {
            if (handCard[i] % 100 == data[j]) {
                // 给牌的花色赋值
                data[j] = handCard[i];
                auto tmp = std::find(handCard.begin(), handCard.end(), data[j]);
                if(tmp != handCard.end()) {
                    handCard.erase(tmp);
                }
                break;
            }
        }
    }
}

// 实际出牌,检测牌型为其配上音乐音效
void PokerPlayer::doCardOut(std::vector< int32_t >& data) {
    if(data.empty()) {
        if((rand() % 2) == 1) {
            SimpleAudioEngine::getInstance()->playEffect("sound/game/female_voice/female_no.mp3");
        } else {
            SimpleAudioEngine::getInstance()->playEffect("sound/game/female_voice/female_pass.mp3");
        }
    } else {
        SimpleAudioEngine::getInstance()->playEffect("sound/effect/Playing_cards.mp3");
        // 获取到状态
        CARDS_DATA dataInfo = PokerLogic::CheckCardType(data);
        std::string strEffect;
        switch(dataInfo._type) {
            case CARD_TYPE::SINGLE_CARD :
                if(dataInfo._cards.size() >= 5) {
                    strEffect = "sound/game/female_voice/female_shunzi.mp3";
                } else {
                    strEffect = utility::toString("sound/game/female_voice/female_", dataInfo._cards[0], ".mp3");
                }
                break;
            case CARD_TYPE::DOUBLE_CARD :
                if(dataInfo._cards.size() > 2) {
                    strEffect = "sound/game/female_voice/female_continuous_pair.mp3";
                } else {
                    strEffect = utility::toString("sound/game/female_voice/female_pair", dataInfo._cards[0], ".mp3");
                }
                break;
            case CARD_TYPE::THREE_CARD :
                if(dataInfo._cards.size() > 3) {
                    strEffect = "sound/game/female_voice/female_airplane.mp3";
                } else {
                    strEffect = "sound/game/female_voice/female_three_one.mp3";
                }
                break;
            case CARD_TYPE::THREE_ONE_CARD :
                if(dataInfo._cards.size() > 4) {
                    strEffect = "sound/game/female_voice/female_airplane_with_wing.mp3";
                } else {
                    strEffect = "sound/game/female_voice/female_three_with_one.mp3";
                }
                break;
            case CARD_TYPE::THREE_TWO_CARD :
                if(dataInfo._cards.size() > 5) {
                    strEffect = "sound/game/female_voice/female_airplane_with_wing.mp3";
                } else {
                    strEffect = "sound/game/female_voice/female_three_with_one_pair.mp3";
                }
                break;
            case CARD_TYPE::BOMB_ONE_CARD :
                //strEffect = "sound/game/female_voice/female_no.mp3";
                break;
            case CARD_TYPE::BOMB_TWO_CARD :
                if(dataInfo._cards.size() > 6) {
                    strEffect = "sound/game/female_voice/female_airplane_with_wing.mp3";
                } else {
                    strEffect = "sound/game/female_voice/female_four_with_two.mp3";
                }
                break;
            case CARD_TYPE::BOMB_TWOO_CARD :
                if(dataInfo._cards.size() > 6) {
                    strEffect = "sound/game/female_voice/female_airplane_with_wing.mp3";
                } else {
                    strEffect = "sound/game/female_voice/female_four_with_two.mp3";
                }
                break;
            case CARD_TYPE::BOMB_TWOOO_CARD :
                if(dataInfo._cards.size() > 8) {
                    strEffect = "sound/game/female_voice/female_airplane_with_wing.mp3";
                } else {
                    strEffect = "sound/game/female_voice/female_four_with_two_pair.mp3";
                }
                break;
            case CARD_TYPE::BOMB_CARD :
                //SimpleAudioEngine::getInstance()->playEffect("sound/effect/bomb.mp3");
                if(dataInfo._cards.size() > 4) {
                    strEffect = "sound/game/female_voice/female_airplane.mp3";
                } else {
                    strEffect = "sound/game/female_voice/female_bomb.mp3";
                }
                break;
            case CARD_TYPE::MISSILE_CARD :
                //SimpleAudioEngine::getInstance()->playEffect("sound/effect/bomb.mp3");
                strEffect = "sound/game/female_voice/female_rocket.mp3";
                break;
            default:
                break;
        }
        if(!strEffect.empty()) {
            SimpleAudioEngine::getInstance()->playEffect(strEffect.c_str());
        }
        DelayCall::add([this](int tick, bool last, int& count){
            if(m_cards.size() == 1) {
                SimpleAudioEngine::getInstance()->playEffect("sound/game/female_voice/female_I_got_left_one_cards.mp3");
            } else if(m_cards.size() == 2) {
                SimpleAudioEngine::getInstance()->playEffect("sound/game/female_voice/female_I_got_left_two_cards.mp3");
            }
        }, 0.1f);
    }
    BasePlayer::doCardOut(data);
}

// 自己先手,别人跟牌,先手的时候就可以随心所欲没有牌型要求
std::vector<int32_t>& PokerPlayer::selectCard(bool forSuggestTips) {
    static std::vector<int32_t> tmp;
    tmp.clear();
    // 分析手牌的类型，看看是不是可以一把全出
    CARDS_DATA theCardInfo = PokerLogic::CheckCardType(m_cards);
    if(theCardInfo._type != CARD_TYPE::ERROR_CARD) {
        // 一把全出!
        for (auto&& one : m_cards) {
            tmp.emplace_back(one % 100); // 去掉花色，留下数字
        }
        return tmp;
    }
    uint8_t master = PokerLogic::shard()->getMasterSeat();
    uint8_t seat1 = PokerLogic::shard()->getRealSeat(m_seat, -1);
    uint8_t seat2 = PokerLogic::shard()->getRealSeat(m_seat, -2);
    // TODO: 这块需要好好想想，逻辑总感觉不够优美
    bool delaySigle = false;//尽量不出单张
    if(m_seat == master) {
        // 自己就是地主，单兵作战，随便出吧
        int nCardCount1 = PokerLogic::shard()->getPlayer(seat1)->getCardCount();
        int nCardCount2 = PokerLogic::shard()->getPlayer(seat2)->getCardCount();
        if (nCardCount1 <= 3 || nCardCount2 <= 3) {
            // 尽量不出单张
            delaySigle = true;
        }
    } else {
        int countMaster = 0;
        int countPartner = 0;
        // 自己是农民, 需要关注下别人的手牌数量
        if (seat1 == master) {
            countMaster = PokerLogic::shard()->getPlayer(seat1)->getCardCount();
            countPartner = PokerLogic::shard()->getPlayer(seat2)->getCardCount();
        } else if (seat2 == master) {
            countMaster = PokerLogic::shard()->getPlayer(seat2)->getCardCount();
            countPartner = PokerLogic::shard()->getPlayer(seat1)->getCardCount();
        }
        if(countPartner == 1 && countMaster > 3) {
            // 单张，协助同伴出去，找最小的单牌，拆牌也在所不惜
            tmp.emplace_back(m_cards[ m_cards.size() - 1 ]);
        } else if(countPartner <= 4 && countMaster > 3) {
            // 协助同伴出去，尽量出对子试试看
            for(auto&& iter : theCardGroups) {
                if(iter._type == CARD_TYPE::DOUBLE_CARD && iter._cards.size() == 2) {
                    if(tmp.empty() || tmp[0] > iter._cards[0]) {
                        tmp = iter._cards;
                    }
                }
            }
            if(tmp.empty()) {
                // 没有合适的对子就找最小的单牌
                tmp.emplace_back(m_cards[ m_cards.size() - 1 ]);
            }
        } else if(countMaster <= 3) {
            // 地主快没牌了,尽量不出单张
            delaySigle = true;
        }
    }
    if(tmp.empty()) {
        // 不同牌组优先级
        std::vector< std::tuple<int, CARD_TYPE> > orderInfo = {
            {10, CARD_TYPE::DOUBLE_CARD}   // 双顺，至少5对
            , {9, CARD_TYPE::THREE_CARD}   // 飞机，至少9张牌
            , {8, CARD_TYPE::DOUBLE_CARD}  // 双顺，至少4对
            , {6, CARD_TYPE::THREE_CARD}   // 飞机，至少6张牌
            , {6, CARD_TYPE::DOUBLE_CARD}  // 双顺，至少3对
            , {8, CARD_TYPE::SINGLE_CARD}  // 单顺，至少8张牌
            , {5, CARD_TYPE::SINGLE_CARD}  // 单顺，至少5张牌
            , {3, CARD_TYPE::THREE_CARD}   // 三张，至少3张牌
        };
        if (delaySigle) {
            // 尽量不出单张
            orderInfo.push_back({ 2, CARD_TYPE::DOUBLE_CARD });  // 对子，至少2张牌
            orderInfo.push_back({ 4, CARD_TYPE::BOMB_CARD });    // 炸弹，至少4张牌
            orderInfo.push_back({ 1, CARD_TYPE::ONLY_CARD });    // 绝对单牌，至少1张牌
            orderInfo.push_back({ 1, CARD_TYPE::SINGLE_CARD });  // 单牌，至少1张牌
            orderInfo.push_back({ 2, CARD_TYPE::MISSILE_CARD }); // 火箭，至少2张牌
        } else {
            orderInfo.push_back({ 1, CARD_TYPE::ONLY_CARD });    // 绝对单牌，至少1张牌
            orderInfo.push_back({ 2, CARD_TYPE::DOUBLE_CARD });  // 对子，至少2张牌
            orderInfo.push_back({ 1, CARD_TYPE::SINGLE_CARD });  // 单牌，至少1张牌
            orderInfo.push_back({ 4, CARD_TYPE::BOMB_CARD });    // 炸弹，至少4张牌
            orderInfo.push_back({ 2, CARD_TYPE::MISSILE_CARD }); // 火箭，至少2张牌
        }
        // 开始挨个检查看哪个牌型可以出牌
        for (auto&& theType : orderInfo) {
            size_t nCardCount = std::get<0>(theType);
            CARD_TYPE theCardType = std::get<1>(theType);
            CARD_TYPE findType = CARD_TYPE::ERROR_CARD;
            for(auto&& iter : theCardGroups) {
                if(!tmp.empty() && iter._type != findType) {
                    continue;//一次只检查一个类型，不同类型的先跳过
                }
                if(iter._type == theCardType && iter._cards.size() >= nCardCount) {
                    if(CARD_TYPE::ONLY_CARD == theCardType || (CARD_TYPE::SINGLE_CARD == theCardType && iter._cards.size() == 1)) {
                        if (delaySigle && CARD_TYPE::ONLY_CARD == theCardType) {
                            tmp.emplace_back(iter._cards[iter._cards.size() - 1]);// 尽量不出单张, 即使是单张也尽量出大牌
                        } else {
                            tmp.emplace_back(iter._cards[0]);
                        }
                        break;
                    }
                    // tmp 为空
                    // tmp 最小的那张牌比 iter 最小的那张牌大
                    // tmp 牌数比 iter 的张数少
                    if( tmp.empty() || (tmp[0] > iter._cards[0])) {
                        tmp = iter._cards;
                        findType = theCardType;
                    }
                }
            }
            if(!tmp.empty()) {
                if( (theCardType == CARD_TYPE::THREE_CARD) || (theCardType == CARD_TYPE::BOMB_CARD) ) {
                    int baseCount = (theCardType == CARD_TYPE::THREE_CARD ? 3 : 4);
                    int count = (int)(tmp.size() / baseCount);
                    // 找找翅膀
                    std::vector<int32_t> tmp2;
                    for(auto&& iter : theCardGroups) {
                        if(iter._type == CARD_TYPE::ONLY_CARD) { // 先尝试把绝对单张带走
                            for (auto&& one : iter._cards) {
                                if(one < 12) {// 小于2的都尝试带走，2比较大，留着吧。。。
                                    tmp2.emplace_back(one);
                                }
                                if(count == tmp2.size()) {// 张数够了就可以返回
                                    std::copy(tmp2.begin(), tmp2.end(), std::back_inserter(tmp));
                                    return tmp;
                                }
                            }
                        }
                    }
                    tmp2.clear();
                    for(auto&& iter : theCardGroups) { // 单张不够，那就尝试带对子
                        if(iter._type == CARD_TYPE::DOUBLE_CARD) {
                            size_t i = 0;
                            while(i < iter._cards.size()) {
                                tmp2.emplace_back(iter._cards[i++]);
                                tmp2.emplace_back(iter._cards[i++]);
                                if(count * 2 == tmp2.size()) {
                                    std::copy(tmp2.begin(), tmp2.end(), std::back_inserter(tmp));
                                    return tmp;
                                }
                            }
                        }
                    }
                }
                break;
            }
        }
        if(tmp.empty()) {
            DebugLogWrite("不科学啊，为毛能走到这里?!!!\n");
            tmp.emplace_back(m_cards[ m_cards.size() - 1 ]);
        }
    }
    return tmp;
}

std::vector<int32_t>& PokerPlayer::selectCard(uint8_t seat, std::vector< int32_t >& cardsLastOut, bool forSuggestTips) {
    // 根据别人的牌,优选自己的出牌方式,必须能大过对方
    static std::vector<int32_t> tmp;
    size_t count = cardsLastOut.size();
    // 分析对手牌的类型
    CARDS_DATA outData = PokerLogic::CheckCardType(cardsLastOut);
    uint8_t seatMaster = PokerLogic::shard()->getMasterSeat();
    uint8_t seat1 = PokerLogic::shard()->getRealSeat(m_seat, -1);
    uint8_t seat2 = PokerLogic::shard()->getRealSeat(m_seat, -2);
    size_t nCardCount1 = PokerLogic::shard()->getPlayer(seat1)->getCardCount();
    size_t nCardCount2 = PokerLogic::shard()->getPlayer(seat2)->getCardCount();
    bool iAmBose = (m_seat == seatMaster);// 自己是地主, 地主没朋友, 尽是敌人
    size_t nCardEnemy = (iAmBose ? MIN(nCardCount1, nCardCount2) : (seat1 == seatMaster ? nCardCount1 : nCardCount2));
    tmp.clear();
    switch(outData._type) {
        case CARD_TYPE::SINGLE_CARD :
            if(count == 1) {
                // 单牌
                if (nCardEnemy <= 3 && (m_cards[0] % 100) > outData._cards[0]) {
                    // 敌方快没牌了, 找大的出
                    tmp.emplace_back(m_cards[0] % 100);
                    return tmp;
                }
                for(auto&& iter : theCardGroups) {
                    if(iter._type == CARD_TYPE::ONLY_CARD) {
                        for (auto&& one : iter._cards) {
                            if(one > outData._cards[0]) {
                                tmp.emplace_back(one);
                                return tmp;
                            }
                        }
                    }
                }
                // 这里也不够优美，拆出去的也许是顺子，也许应该检查下是不是可以拆对子或者飞机
                for(auto&& iter : theCardGroups) {
                    if(iter._type == CARD_TYPE::SINGLE_CARD && iter._cards.size() == 1 && iter._cards[0] > outData._cards[0]) {
                        tmp.emplace_back(iter._cards[0]);
                        return tmp;
                    }
                }
                for(auto&& iter : theCardGroups) {
                    if(iter._type == CARD_TYPE::THREE_CARD
                       && iter._cards.size() == 3 // 尝试拆三张
                       && iter._cards[0] > outData._cards[0]
                       ) {
                        tmp.emplace_back(iter._cards[0]);
                        return tmp;
                    }
                }
                if(forSuggestTips || ((seat == seatMaster || m_seat == seatMaster) && PokerLogic::shard()->getPlayer(seat)->getCardCount() <= 3)) {
                    // 随意拆牌
                    for (auto&& one : m_cards) {
                        if((one % 100) > outData._cards[0]) {
                            tmp.emplace_back(one);
                            return tmp;
                        }
                    }
                }
            } else {
                // 顺子
                for(auto&& iter : theCardGroups) {
                    if(iter._type == CARD_TYPE::SINGLE_CARD
                       && iter._cards.size() >= count
                       && (forSuggestTips || iter._cards.size() <= count + 4)
                       && iter._cards[iter._cards.size() - 1] > outData._cards[outData._cards.size() - 1]) {
                        if(iter._cards.size() == count) {
                            tmp = iter._cards;
                            break;
                        }
                        std::copy(iter._cards.begin() + (iter._cards.size() - count), iter._cards.end(), std::back_inserter(tmp));
                        break;
                    }
                }
            }
            break;
        case CARD_TYPE::DOUBLE_CARD : // 对子
            for(auto&& iter : theCardGroups) {
                if(iter._type == CARD_TYPE::DOUBLE_CARD
                   && iter._cards.size() == count // 优先找完全匹配的
                   && iter._cards[iter._cards.size() - 1] > outData._cards[outData._cards.size() - 1]
                   ) {
                    tmp = iter._cards;
                    return tmp;
                }
            }
            for(auto&& iter : theCardGroups) {
                if(iter._type == CARD_TYPE::DOUBLE_CARD
                   && iter._cards.size() >= count // 没有完全匹配的那就浪费一点找长度大一点的看看
                   && iter._cards[iter._cards.size() - 1] > outData._cards[outData._cards.size() - 1]
                   ) {
                    std::copy(iter._cards.begin() + (iter._cards.size() - count), iter._cards.end(), std::back_inserter(tmp));
                    return tmp;
                }
            }
            if(count == 2) {// 标准对子
                for(auto&& iter : theCardGroups) {
                    if(iter._type == CARD_TYPE::THREE_CARD
                       && (forSuggestTips || iter._cards.size() == 3) // 尝试拆三张
                       && iter._cards[0] > outData._cards[0]
                       ) {
                        tmp.emplace_back(iter._cards[0]);
                        tmp.emplace_back(iter._cards[1]);
                        return tmp;
                    }
                }
            } else {
                // 连对，看看是不是能拆连三
                for(auto&& iter : theCardGroups) {
                    if(iter._type == CARD_TYPE::THREE_CARD
                       && iter._cards.size() >= (count * 1.5)
                       && iter._cards[0] > outData._cards[0]
                       ) {
                        size_t index = 0;
                        while(index < iter._cards.size()) {
                            tmp.emplace_back(iter._cards[index++]);
                            tmp.emplace_back(iter._cards[index++]);
                            index++;
                            if(tmp.size() == count) {
                                return tmp;
                            }
                        }
                        return tmp;
                    }
                }
            }
            break;
        case CARD_TYPE::THREE_CARD : // 三张
        case CARD_TYPE::THREE_ONE_CARD : // 3带1，三张并带上任意一张牌
        case CARD_TYPE::THREE_TWO_CARD : // 3带2，三张并带上一对
        {
            // 检查下有几个三张，需要确认是不是多个小飞机
            size_t len = (size_t)(outData._type == CARD_TYPE::THREE_TWO_CARD ? (count / 5)
                       : (outData._type == CARD_TYPE::THREE_ONE_CARD ? (count / 4) : (count / 3)));
            for(auto&& iter : theCardGroups) {
                if(iter._type == CARD_TYPE::THREE_CARD
                   && iter._cards.size() >= len * 3
                   && iter._cards[iter._cards.size() - 1] > outData._cards[len * 3 - 1]) {
                    std::copy(iter._cards.begin() + (iter._cards.size() - len * 3), iter._cards.end(), std::back_inserter(tmp));
                    if(tmp.size() < count) { // 张数对不上，对方带有翅膀，我也要带上翅膀
                        // 找找翅膀
                        std::vector<int32_t> tmp2;
                        if(outData._type == CARD_TYPE::THREE_ONE_CARD) {
                            for(auto&& iter : theCardGroups) {
                                if(iter._type == CARD_TYPE::ONLY_CARD){
                                    for (auto&& one : iter._cards) {//三带1
                                        tmp2.emplace_back(one);
                                        if(count == tmp2.size() + tmp.size()) {// 张数够了就可以返回
                                            std::copy(tmp2.begin(), tmp2.end(), std::back_inserter(tmp));
                                            return tmp;
                                        }
                                    }
                                }
                            }
                            for(auto&& iter : theCardGroups) {
                                if(iter._type == CARD_TYPE::SINGLE_CARD){
                                    for (auto&& one : iter._cards) {//三带1
                                        tmp2.emplace_back(one);
                                        if(count == tmp2.size() + tmp.size()) {// 张数够了就可以返回
                                            std::copy(tmp2.begin(), tmp2.end(), std::back_inserter(tmp));
                                            return tmp;
                                        }
                                    }
                                }
                            }
                        } else if(outData._type == CARD_TYPE::THREE_TWO_CARD) {
                            for(auto&& iter : theCardGroups) {
                                if(iter._type == CARD_TYPE::DOUBLE_CARD) {
                                    size_t i = 0;
                                    while(i < iter._cards.size()) {//三带2
                                        tmp2.emplace_back(iter._cards[i++]);
                                        tmp2.emplace_back(iter._cards[i++]);
                                        if(count == tmp2.size() + tmp.size()) {
                                            std::copy(tmp2.begin(), tmp2.end(), std::back_inserter(tmp));
                                            return tmp;
                                        }
                                    }
                                }
                            }
                            if(nCardEnemy < 5) {
                                // 炸死他！
                                for(auto&& iter : theCardGroups) {
                                    if(iter._type == CARD_TYPE::BOMB_CARD) {
                                        tmp.clear();
                                        tmp.emplace_back(iter._cards[0]);
                                        tmp.emplace_back(iter._cards[1]);
                                        tmp.emplace_back(iter._cards[2]);
                                        tmp.emplace_back(iter._cards[3]);
                                        break;
                                    }
                                }
                                for(auto&& iter : theCardGroups) {
                                    if(iter._type == CARD_TYPE::THREE_CARD) {
                                        size_t i = 0;
                                        while(i < iter._cards.size()) {//三带2
                                            tmp2.emplace_back(iter._cards[i++]);
                                            tmp2.emplace_back(iter._cards[i++]);
                                            i++;
                                            if(count == tmp2.size() + tmp.size()) {
                                                std::copy(tmp2.begin(), tmp2.end(), std::back_inserter(tmp));
                                                return tmp;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    break;
                }
            }
        }
            break;
        case CARD_TYPE::BOMB_ONE_CARD : // 四张带上一个单张
        case CARD_TYPE::BOMB_TWO_CARD : // 四张带上两个单张
        case CARD_TYPE::BOMB_TWOO_CARD : // 四张带上1对
        case CARD_TYPE::BOMB_TWOOO_CARD : // 四张带上2对
        case CARD_TYPE::BOMB_CARD : // 炸弹
        {
            // 检查下有几个四张，需要确认是不是多个大飞机
            int len = 0;
            len = (int)(outData._type == CARD_TYPE::BOMB_ONE_CARD ? (count / 5) : len);
            len = (int)(outData._type == CARD_TYPE::BOMB_TWO_CARD ? (count / 6) : len);
            len = (int)(outData._type == CARD_TYPE::BOMB_TWOO_CARD ? (count / 6) : len);
            len = (int)(outData._type == CARD_TYPE::BOMB_TWOOO_CARD ? (count / 8) : len);
            len = (int)(outData._type == CARD_TYPE::BOMB_CARD ? (count / 4) : len);
            // 开始查找
            for(auto&& iter : theCardGroups) {
                if(iter._type == CARD_TYPE::BOMB_CARD
                   && iter._cards.size() == len * 4
                   && iter._cards[iter._cards.size() - 1] > outData._cards[len * 4 - 1]) {
                    tmp = iter._cards;
                    if(tmp.size() < count) { // 张数对不上，对方带有翅膀，我也要带上翅膀
                        // 找找翅膀
                        std::vector<int32_t> tmp2;
                        if(outData._type == CARD_TYPE::BOMB_ONE_CARD || outData._type == CARD_TYPE::BOMB_TWO_CARD) {
                            for(auto&& iter : theCardGroups) {
                                if(iter._type == CARD_TYPE::ONLY_CARD){
                                    for (auto&& one : iter._cards) {//四带1单，四带2单
                                        tmp2.emplace_back(one);
                                        if(count == tmp2.size() + tmp.size()) {// 张数够了就可以返回
                                            std::copy(tmp2.begin(), tmp2.end(), std::back_inserter(tmp));
                                            return tmp;
                                        }
                                    }
                                }
                            }
                            for(auto&& iter : theCardGroups) {
                                if(iter._type == CARD_TYPE::SINGLE_CARD){
                                    for (auto&& one : iter._cards) {//四带1单，四带2单
                                        tmp2.emplace_back(one);
                                        if(count == tmp2.size() + tmp.size()) {// 张数够了就可以返回
                                            std::copy(tmp2.begin(), tmp2.end(), std::back_inserter(tmp));
                                            return tmp;
                                        }
                                    }
                                }
                            }
                        } else if(outData._type == CARD_TYPE::BOMB_TWOO_CARD || outData._type == CARD_TYPE::BOMB_TWOOO_CARD) {
                            for(auto&& iter : theCardGroups) {
                                if(iter._type == CARD_TYPE::DOUBLE_CARD) {
                                    size_t i = 0;
                                    while(i < iter._cards.size()) {//三带2
                                        tmp2.emplace_back(iter._cards[i++]);
                                        tmp2.emplace_back(iter._cards[i++]);
                                        if(count == tmp2.size() + tmp.size()) {
                                            std::copy(tmp2.begin(), tmp2.end(), std::back_inserter(tmp));
                                            return tmp;
                                        }
                                    }
                                }
                            }
                        }
                    }
                    break;
                }
            }
        }
            break;
        default:
            break;
    }
    if(!tmp.empty() && tmp.size() != count) {
        tmp.clear();// 张数对不上，说明牌不够用，放弃吧
    }
    int random = rand() % 100;
    if(tmp.empty() && outData._type != CARD_TYPE::BOMB_CARD && outData._type != CARD_TYPE::MISSILE_CARD && (random < 27 || nCardEnemy <= 7 || forSuggestTips)) {
        // 炸死他！
        DebugLogWrite("BOMB_CARD - random[%d] - CardEnemy[%d]\n", random, nCardEnemy);
        for(auto&& iter : theCardGroups) {
            if(iter._type == CARD_TYPE::BOMB_CARD) {
                tmp.emplace_back(iter._cards[0]);
                tmp.emplace_back(iter._cards[1]);
                tmp.emplace_back(iter._cards[2]);
                tmp.emplace_back(iter._cards[3]);
                break;
            }
        }
    }
    if(tmp.empty() && (random < 15 || nCardEnemy <= 5 || forSuggestTips)) {
        // 火箭
        DebugLogWrite("MISSILE_CARD - random[%d] - CardEnemy[%d]\n", random, nCardEnemy);
        for(auto&& iter : theCardGroups) {
            if(iter._type == CARD_TYPE::MISSILE_CARD) {
                tmp.emplace_back(iter._cards[0]);
                tmp.emplace_back(iter._cards[1]);
                break;
            }
        }
    }
    return tmp;
}

